﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="StudyAddViewModel.cs" company="ELEN 7045 GROUP II">>
//   
// </copyright>
// <summary>
//   The Studies View Model.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Presentation.Module.StudyDefinition.ViewModels
{
    #region

    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Windows.Input;

    using Microsoft.Practices.Prism.Commands;
    using Microsoft.Practices.Prism.Regions;

    using Presentation.Module.StudyDefinition.Interfaces.Services;
    using Presentation.Module.StudyDefinition.Interfaces.ViewModels;
    using Presentation.Module.StudyDefinition.Interfaces.Views;
    using Presentation.Module.StudyDefinition.Models;

    #endregion

    /// <summary>
    /// StudyAddViewModel Implementation
    /// </summary>
    public class StudyAddViewModel : StudyDefinitionViewModelBase, IStudyAddViewModel, INotifyPropertyChanged
    {
        #region Constants and Fields

        /// <summary>
        /// The available subject groups.
        /// </summary>
        private ObservableCollection<SubjectGroup> availableSubjectGroups;

        /// <summary>
        /// The available treatments.
        /// </summary>
        private ObservableCollection<Treatment> availableTreatments;

        /// <summary>
        /// A study item
        /// </summary>
        private Study currentItem;


        /// <summary>
        /// The selected treatment.
        /// </summary>
        private Treatment selectedTreatment;

        /// <summary>
        /// The selected treatments.
        /// </summary>
        private ObservableCollection<Treatment> selectedTreatments;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="StudyAddViewModel"/> class.
        /// </summary>
        /// <param name="regionManager">
        /// The region manager.
        /// </param>
        /// <param name="studiesService">
        /// The studies service.
        /// </param>
        public StudyAddViewModel(IRegionManager regionManager, IStudiesUIProxyService studiesService)
            : base(regionManager, studiesService)
        {
            /* ... Relies on abstract base class for dependencies. */

            // Setting up command delegates 
            this.AddStudy = new DelegateCommand(this.OnAddStudy);

            // this.AddSubjectGroupToStudy = new DelegateCommand<SubjectGroup>(this.OnAddSubjectGroupToStudy);
            // this.RemoveSubjectGroupFromStudy = new DelegateCommand<SubjectGroup>(this.OnRemoveSubjectGroupFromStudy);
            this.LinkSubjectGroupToSelectedTreatment =
                new DelegateCommand<SubjectGroup>(this.OnLinkSubjectGroupToSelectedTreatment);
            this.AddTreatmentToStudy = new DelegateCommand<Treatment>(this.OnAddTreatmentToStudy);

            // this.Add = new DelegateCommand<Treatment>(this.OnAddTreatmentToStudy);
            this.SelectTreatment = new DelegateCommand<Treatment>(this.OnSelectTreatment);
        }

        #endregion

        #region Events

        /// <summary>
        /// Occurs when a property value changes.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Properties

        /// <summary>
        /// Gets the add study command.
        /// </summary>
        public ICommand AddStudy { get; set; }

        /// <summary>
        /// Gets or sets AddSubjectGroupToStudy.
        /// </summary>
        public ICommand AddSubjectGroupToStudy { get; set; }

        /// <summary>
        /// Gets AddTreatmentToStudy.
        /// </summary>
        public ICommand AddTreatmentToStudy { get; private set; }

        /// <summary>
        /// Gets or sets AvailableSubjectGroups.
        /// </summary>
        public ObservableCollection<SubjectGroup> AvailableSubjectGroups
        {
            get
            {
                this.availableSubjectGroups=this.StudiesServiceInstance.GetAllSubjectGroups();
                
                return availableSubjectGroups;
            } 

            set
            {
                this.availableSubjectGroups = value;
                this.RaiseOnPropertyChanged("AvailableSubjectGroups");
            }
        }

        /// <summary>
        /// Gets or sets the available treatments.
        /// </summary>
        /// <value>
        /// The available treatments.
        /// </value>
        public ObservableCollection<Treatment> AvailableTreatments
        {
            get
            {
                this.availableTreatments = this.StudiesServiceInstance.GetAllTreatments();

                // this.RaiseOnPropertyChanged("AvailableTreatments");
                return this.availableTreatments;
            }

            set
            {
                this.availableTreatments = value;
                this.RaiseOnPropertyChanged("AvailableTreatments");
            }
        }

        /// <summary>
        /// Gets or sets CurrentItem.
        /// </summary>
        public Study CurrentItem
        {
            get
            {
                return this.currentItem;
            }

            set
            {
                if (value == null)
                {
                    return;
                }

                this.currentItem = value;
                this.RaiseOnPropertyChanged("CurrentItem");
            }
        }

        /// <summary>
        /// Gets LinkSubjectGroupToSelectedTreatment.
        /// </summary>
        public ICommand LinkSubjectGroupToSelectedTreatment { get; private set; }

        /// <summary>
        /// Gets or sets RemoveSubjectGroupFromStudy.
        /// </summary>
        public ICommand RemoveSubjectGroupFromStudy { get; set; }

        /// <summary>
        /// Gets RemoveTreatmentFromStudy.
        /// </summary>
        public ICommand RemoveTreatmentFromStudy { get; private set; }

        /// <summary>
        /// Gets SelectTreatment.
        /// </summary>
        public ICommand SelectTreatment { get; private set; }

        /// <summary>
        /// Gets or sets the selected treatment.
        /// </summary>
        /// <value>
        /// The selected treatment.
        /// </value>
        public Treatment SelectedTreatment
        {
            get
            {
                return this.selectedTreatment;
            }

            set
            {
                this.selectedTreatment = value;
                this.RaiseOnPropertyChanged("SelectedTreatment");
            }
        }

        /// <summary>
        /// Gets or sets the selected treatments.
        /// </summary>
        /// <value>
        /// The selected treatments.
        /// </value>
        public ObservableCollection<Treatment> SelectedTreatments
        {
            get
            {
                return this.selectedTreatments;
            }

            set
            {
                this.selectedTreatments = value;
                this.RaiseOnPropertyChanged("SelectedTreatments");
            }
        }

        // public void OnAddSubjectGroupToStudy (SubjectGroup subjectGroup)
        // {
        // if(subjectGroup==null)
        // {
        // return;
        // }

        // this.CurrentItem.SubjectGroups.Add(subjectGroup);
        // this.RaiseOnPropertyChanged("CurrentItem");

        // this.AvailableSubjectGroups.Remove(subjectGroup);
        // this.RaiseOnPropertyChanged("AvailableSubjectGroups");
        // }

        // public void OnRemoveSubjectGroupFromStudy(SubjectGroup subjectGroup)
        // {
        // if (subjectGroup == null)
        // {
        // return;
        // }

        // this.AvailableSubjectGroups.Add(subjectGroup);
        // this.RaiseOnPropertyChanged("AvailableSubjectGroups");

        // this.CurrentItem.SubjectGroups.Remove(subjectGroup);
        // this.RaiseOnPropertyChanged("CurrentItem");
        // }

        /// <summary>
        /// Gets or sets the view.
        /// </summary>
        /// <value>
        /// The study add view.
        /// </value>
        public IStudyAddView View { get; set; }

        #endregion

        #region Implemented Interfaces

        #region IStudyAddViewModel

        /// <summary>
        /// The initialize.
        /// </summary>
        public void Initialize()
        {
            this.SelectedTreatments = new ObservableCollection<Treatment>();

            // Populate the current item to for use by the view.
            this.CurrentItem = new Study();

            this.CurrentItem.Treatments = new ObservableCollection<Treatment>();

            // this.CurrentItem.SubjectGroups = new ObservableCollection<SubjectGroup>();
            this.RaiseOnPropertyChanged("CurrentItem");

            // Populate initial values in model properties.
            this.AvailableSubjectGroups = this.StudiesServiceInstance.GetAllSubjectGroups();
            this.RaiseOnPropertyChanged("AvailableSubjectGroups");
        }

        /// <summary>
        /// Called when [add study].
        /// </summary>


        public void OnAddStudy()
        {
            if (SelectedTreatments != null)
            {
                foreach (var treatment in SelectedTreatments)
                {
                    this.CurrentItem.Treatments.Add(treatment);
                }
            }

            // this.AvailableSubjectGroups = availableSubjectGroups;);
            this.StudiesServiceInstance.AddStudy(this.CurrentItem);
            this.CurrentItem = new Study();
            this.RaiseOnPropertyChanged("CurrentItem");

            this.SelectedTreatments= new ObservableCollection<Treatment>();
            this.RaiseOnPropertyChanged("SelectedTreatments");

            this.selectedTreatment = null;
            this.RaiseOnPropertyChanged("SelectedTreatment");
        }

        /// <summary>
        /// The on add treatment to study.
        /// </summary>
        /// <param name="treatment">
        /// The treatment.
        /// </param>
        public void OnAddTreatmentToStudy(Treatment treatment)
        {
            if(treatment==null)
            {
                return;
            }

            this.SelectedTreatments.Add(treatment);
            this.RaiseOnPropertyChanged("SelectedTreatments");

        }

        /// <summary>
        /// The on link subject group to selected treatment.
        /// </summary>
        /// <param name="subjectGroup">
        /// The subject group.
        /// </param>
        public void OnLinkSubjectGroupToSelectedTreatment(SubjectGroup subjectGroup)
        {
            if (subjectGroup == null)
            {
                return;
            }

            if (this.SelectedTreatment.SubjectGroups==null)
            {
                this.SelectedTreatment.SubjectGroups = new ObservableCollection<SubjectGroup>();
            }

            this.SelectedTreatment.SubjectGroups.Add(subjectGroup);
            this.RaiseOnPropertyChanged("SelectedTreatment");
        }

        /// <summary>
        /// The on remove treatment from study.
        /// </summary>
        /// <param name="treatment">
        /// The treatment.
        /// </param>
        public void OnRemoveTreatmentFromStudy(Treatment treatment)
        {
            if (treatment == null)
            {
                return;
            }

            this.CurrentItem.Treatments.Remove(treatment);
        }

        /// <summary>
        /// The on select treatment.
        /// </summary>
        /// <param name="treatment">
        /// The treatment.
        /// </param>
        public void OnSelectTreatment(Treatment treatment)
        {
            if (treatment == null)
            {
                return;
            }

            this.SelectedTreatment = treatment;
        }

        #endregion

        #endregion

        #region Methods

        /// <summary>
        /// Raises the on property changed.
        /// </summary>
        /// <param name="propertyName">
        /// Name of the property.
        /// </param>
        protected void RaiseOnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Called when [cancel].
        /// </summary>
        private void OnCancel()
        {
            this.RegionManagerInstance.Regions["MainRegion"].Deactivate(this.View);
        }

        #endregion
    }
}
